#ifndef YVM_ACCESSFLAG_H
#define YVM_ACCESSFLAG_H

enum class ClassAccess {
    ACC_PUBLIC = 0x0001,
    // Declared public; may be accessed from outside its package. 声明为 public； 可以从其包外部访问。
    ACC_FINAL = 0x0010,
    // Declared final; no subclasses allowed. 声明 final，不允许有子类。
    ACC_SUPER = 0x0020,
    // Treat superclass methods specially when invoked by the invokespecial instruction.
    // 当被 invokespecial 指令调用时，特别对待超类方法。
    ACC_INTERFACE = 0x0200,
    // Is an interface, not a class. 是一个接口，而不是一个类。
    ACC_ABSTRACT = 0x0400,
    // Declared abstract; must not be instantiated. 声明为 abstract; 不得实例化。
    ACC_SYNTHETIC = 0x1000,
    // Declared synthetic; not present in the source code. 声明为 synthetic; 源代码中不存在。
    ACC_ANNOTATION = 0x2000,
    // Declared as an annotation type. 声明为注释类型。
    ACC_ENUM = 0x4000  // Declared as an enum type. 声明为枚举类型。
};

enum class MethodAccess {
    ACC_PUBLIC = 0X0001,
    // Declared public; may be accessed from outside its package. 声明为 public; 可以从其包外部访问。
    ACC_PRIVATE = 0X0002,
    // Declared private; accessible only within the defining class. 声明为 private; 只能在定义类中访问。
    ACC_PROTECTED = 0X0004,
    // Declared protected; may be accessed within subclasses. 声明为 protected（受保护）; 可以在子类中访问。
    ACC_STATIC = 0X0008,
    // Declared static. 声明为 static
    ACC_FINAL = 0X0010,
    // Declared final; must not be overridden. 声明为 final; 不能被覆盖。
    ACC_SYNCHRONIZED = 0X0020,
    // Declared synchronized; invocation is wrapped by a monitor use. 声明为 synchronized; 调用由监视器使用包装。
    ACC_BRIDGE = 0X0040,
    // A bridge method, generated by the compiler. 一种桥接方法，由编译器生成。
    ACC_VARARGS = 0X0080,
    // Declared with variable number of arguments. 用可变数量的参数声明。
    ACC_NATIVE = 0X0100,
    // Declared native; implemented in a language other than Java. 声明为 native; 用 Java 以外的语言实现。
    ACC_ABSTRACT = 0X0400,
    // Declared abstract; no implementation is provided. 声明为 abstract; 没有提供实现。
    ACC_STRICT = 0X0800,
    // Declared strictfp; floating-point mode is FPstrict. 声明为 strictfp； 浮点模式是 FPstrict。
    ACC_SYNTHETIC =
        0X1000  // Declared synthetic; not present in the source code.
};

enum class FieldAccess {
    ACC_PUBLIC = 0x0001,
    // Declared public; may be accessed from outside its package. 声明为 public; 可以从其包外部访问。
    ACC_PRIVATE = 0x0002,
    // Declared private; usable only within the defining class. 声明为 private; 仅在定义类中可用。
    ACC_PROTECTED = 0x0004,
    // Declared protected; may be accessed within subclasses. 声明为 protected（受保护）; 可以在子类中访问。
    ACC_STATIC = 0x0008,
    // Declared static.
    ACC_FINAL = 0x0010,
    // Declared final; never directly assigned to after object construction. 声明为 final; 永远不会直接分配给之后的对象构造。
    ACC_VOLATILE = 0x0040,
    // Declared volatile; cannot be cached. 声明为 volatile（易变的）； 无法缓存。
    ACC_TRANSIENT = 0x0080,
    // Declared transient; not written or read by a persistent object manager. 声明为瞬态； 不由持久对象管理器写入或读取。
    ACC_SYNTHETIC = 0x1000,
    // Declared synthetic; not present in the source code. 声明为 synthetic;  源代码中不存在。
    ACC_ENUM = 0x4000  // Declared as an element of an enum. 声明为枚举的元素。
};

#define IS_FIELD(ACC_NAME)                                      \
    inline bool IS_FIELD_##ACC_NAME(int value) {                \
        return (value & (int)FieldAccess::ACC_##ACC_NAME) != 0; \
    }
#define IS_METHOD(ACC_NAME)                                      \
    inline bool IS_METHOD_##ACC_NAME(int value) {                \
        return (value & (int)MethodAccess::ACC_##ACC_NAME) != 0; \
    }
#define IS_CLASS(ACC_NAME)                                      \
    inline bool IS_CLASS_##ACC_NAME(int value) {                \
        return (value & (int)ClassAccess::ACC_##ACC_NAME) != 0; \
    }

IS_METHOD(PUBLIC)
IS_METHOD(PRIVATE)
IS_METHOD(PROTECTED)
IS_METHOD(STATIC)
IS_METHOD(FINAL)
IS_METHOD(SYNCHRONIZED)
IS_METHOD(BRIDGE)
IS_METHOD(VARARGS)
IS_METHOD(NATIVE)
IS_METHOD(ABSTRACT)
IS_METHOD(STRICT)
IS_METHOD(SYNTHETIC)

IS_FIELD(PUBLIC)
IS_FIELD(PRIVATE)
IS_FIELD(PROTECTED)
IS_FIELD(STATIC)
IS_FIELD(FINAL)
IS_FIELD(VOLATILE)
IS_FIELD(TRANSIENT)
IS_FIELD(SYNTHETIC)
IS_FIELD(ENUM)

IS_CLASS(PUBLIC)
IS_CLASS(FINAL)
IS_CLASS(SUPER)
IS_CLASS(INTERFACE)
IS_CLASS(ABSTRACT)
IS_CLASS(SYNTHETIC)
IS_CLASS(ANNOTATION)
IS_CLASS(ENUM)

#endif  // YVM_ACCESSFLAG_H
